package com.xbongbong.pro.aiassistant;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.help.subform.TransferSubFormHelper;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.pro.domain.entity.AiAssistantEntity;
import com.xbongbong.pro.enums.smartsettings.enums.SmartSettingsConditionEnum;
import com.xbongbong.pro.enums.smartsettings.enums.SmartSettingsFieldEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ProductWarehouseEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.dictionary.ArchivedEnum;
import com.xbongbong.saas.enums.dictionary.PayPlanStatusEnum;
import com.xbongbong.saas.enums.dictionary.PaymentStatusEnum;
import com.xbongbong.saas.enums.subform.ProductStockSubFormEnum;
import com.xbongbong.saas.enums.subform.ProductWarehouseSubFormEnum;
import com.xbongbong.saas.model.ProductStockModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.join.query.HasParentQueryBuilder;
import org.elasticsearch.join.query.JoinQueryBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * @author 吴峰
 * @date 2020/09/17 10:48
 */
@Component
public class AiAssistantConditionHelp {

    private static final Logger LOGGER = LoggerFactory.getLogger(AiAssistantConditionHelp.class);
    @Resource
    private ProductStockModel productStockModel;

    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private TransferSubFormHelper transferSubFormHelper;

    /**
     * 是否需要查询关联数据的触发条件
     * 查询关联数据触发条件：待生产、待采购
     * @param allConditionList 所有的触发条件
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-24 16:59
     * @since v1.0
     * @version v1.0
     */
    public  Map<String, Boolean> getLinkDataFlag(List<ConditionsEntityExt> allConditionList) {

        Map<String, Boolean> flagMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        for (ConditionsEntityExt entityExt : allConditionList) {
            Integer fieldType = entityExt.getFieldType();
            SmartSettingsFieldEnum ssFieldEnum = SmartSettingsFieldEnum.getFieldTypeEnum(fieldType);
            if (ssFieldEnum == null) {
                continue;
            }
            switch (ssFieldEnum) {
                // 待生产、待采购
                case WAIT_PURCHASE:
                case WAIT_PRODUCTION_ORDER:
                    flagMap.put(ssFieldEnum.getAlias(), true);
                    break;
                default:
                    break;
            }
        }

        return flagMap;
    }



    /**
     * 获取es查询条件
     *
     * @param entity 智能助手实体
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-05-09 14:57
     * @version v1.0
     * @since v1.0
     */
    public void addConditionList(AiAssistantEntity entity, List<ConditionsEntityExt> conditionList, List<ConditionsEntityExt> birthdayConditionList,
                                    List<ConditionsEntityExt> stockWarningConditionList,
                                    List<ConditionsEntityExt> expireWarningConditionList, Set<Long> waitProduceDataIdSet, Set<Long> waitPurchaseDataIdSet) {
        // 当天时间戳
        long now = DateUtil.getTodayInt();
        List<ConditionsEntityExt> conditions = entity.getTriggerCondition().toJavaList(ConditionsEntityExt.class);
        for (ConditionsEntityExt conditionsEntity : conditions) {
            String attr = conditionsEntity.getAttr();
            Integer fieldType = conditionsEntity.getFieldType();
            String symbol = conditionsEntity.getSymbol();
            List<Object> value = conditionsEntity.getValue();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            SmartSettingsFieldEnum ssFieldEnum = SmartSettingsFieldEnum.getFieldTypeEnum(fieldType);
            // attr、fieldType、symbol、value改为查询的类型
            if (fieldTypeEnum != null) {
                if(Objects.equals(FieldTypeEnum.BIRTHDAY.getType(), fieldType)) {
                    birthdayConditionList.add(conditionsEntity);
                    // 添加生日需要添加非公海客户条件
                    if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), entity.getBusinessType())) {
                        conditionList.add(getNoPublicCustomerCondition());
                    }
                } else {
                    conditionList.add(getConditionByFieldEnum(attr, fieldTypeEnum, symbol, value, now));
                }
            } else if (ssFieldEnum != null) {
                conditionList.addAll(getConditionBySsFieldEnum(entity.getCorpid(), attr, ssFieldEnum, symbol, value, now, waitProduceDataIdSet, waitPurchaseDataIdSet, stockWarningConditionList, expireWarningConditionList));
            }
        }
    }






    /**
     * 获取es查询条件--字段处理
     *
     * @param attr          字段别名
     * @param fieldTypeEnum 字段类型
     * @param symbol        条件
     * @param value         可选值
     * @param now           当前日期
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-05-09 16:04
     * @version v1.0
     * @since v1.0
     */
    public ConditionsEntityExt getConditionByFieldEnum(String attr, FieldTypeEnum fieldTypeEnum, String symbol, List<Object> value, long now) {
        switch (fieldTypeEnum) {
            // TODO 时间区间的界定，提交时间/修改时间/日期
            case ADDTIME:
            case UPDATETIME:
            case DATETIME:
                long day = 0;
                if (value.size() > 0) {
                    day = Long.parseLong(value.get(0).toString());
                }
                // 查询条件为时间区间
                value = getDateRange(now, day, symbol);
                // 条件为区间
                symbol = ConditionEnum.RANGE.getSymbol();
                break;
            // 其他类型的触发值
            case TEXT:
            case RADIO_GROUP:
            case COMBO:
            case CHECKBOX_GROUP:
            case COMBO_CHECK:
            case USER_GROUP:
            case USER:
            case TEXTAREA:
            case CREATORID:
            case LINK_BUSINESS_SINGLE:
                // 联系电话是子表单，以后再处理
                // case CONTACT_NUMBER:
            case STAGE_THRUSTER:
                // 阶段推进器
            case SELECT_PRODUCT:
                // 勾选+下拉选择（执行人）--暂时不添加（2019.8.19）
                // case CHECK_COMBO:
            case SPECIFICATION:
            case RICH_TEXT_EDITOR:
            case STAR:
            case VIDEO:
                List<Object> newValue = getValueBySymbol(symbol, value);
                value.clear();
                value.addAll(newValue);
                break;
            case NUM:
            case DEPT:
            case DEPT_GROUP:
            default:
                break;
        }

        ConditionsEntityExt entityExt = new ConditionsEntityExt();
        // attr、fieldType、symbol、value改为查询的类型
        entityExt.setAttr(attr);
        entityExt.setFieldType(fieldTypeEnum.getType());
        entityExt.setSymbol(symbol);
        entityExt.setValue(value);
        return entityExt;
    }


    public static List<Object> getValueBySymbol(String symbol, List<Object> value) {
        ConditionEnum conditionEnum = ConditionEnum.getConditionEnum(symbol);
        if(Objects.isNull(conditionEnum) || Objects.isNull(value) || value.isEmpty()) {
            return new ArrayList<>();
        }

        List<Object> resultValue = new ArrayList<>();

        // 等于/不等于、等于任意一个/不等于任意一个、包含任意一个/同时包含、包含/不包含、为空/不为空、大于/小于、大于等于/小于等于、选择范围
        switch (conditionEnum) {
            // 等于/不等于、等于任意一个/不等于任意一个、包含任意一个/同时包含
            case EQUAL:
            case NOEQUAL:
            case IN:
            case NOIN:
            case ALLINCLUDE:
            case INCLUDE:
                // 阶段推进器这边存在两种格式[{"text":"确认需求","value":"1"},{"text":"成交阶段","value":"5"}]和["1","2","3"]
                for(Object object : value) {
                    if (object instanceof Map) {
                        JSONObject jsonObject = (JSONObject) object;
                        Object newValue = jsonObject.get("value");
                        resultValue.add(newValue);
                    } else {
                        resultValue.add(object);
                    }
                }
                break;
            // 包含/不包含、大于/小于、大于等于/小于等于、选择范围
            case LIKE:
            case NOLIKE:
            case GREATEREQUAL:
            case LESSEQUAL:
            case GREATERTHAN:
            case LESSTHAN:
            case RANGE:
                resultValue.addAll(value);
                break;
            case NORANGE:
                break;
            case EMPTY:
            case NOEMPTY:
            default:
                break;
        }

        return resultValue;
    }



    /**
     * 获取es查询条件--智能助手特殊字段
     *
     * @param attr        字段别名
     * @param ssFieldEnum 字段类型
     * @param symbol      条件
     * @param value       可选值
     * @param now         当前日期
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-05-09 16:01
     * @version
     * @since
     */
    public List<ConditionsEntityExt> getConditionBySsFieldEnum(String corpid, String attr, SmartSettingsFieldEnum ssFieldEnum, String symbol,
                                                                List<Object> value, long now, Set<Long> waitProduceDataIdSet, Set<Long> waitPurchaseDataIdSet,
                                                                List<ConditionsEntityExt> stockWarningConditionList, List<ConditionsEntityExt> expireWarningConditionList) {
        // 默认文本类型
        List<ConditionsEntityExt> list = new ArrayList<>();
        ConditionsEntityExt entityExt = new ConditionsEntityExt();
        switch (ssFieldEnum) {
            // 遗忘客户
            case FORGET_CUSTOMER:
                value = getForgetDateRange(now, value, symbol);
                // 客户-最近联系时间
                entityExt.setAttr(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr());
                entityExt.setFieldType(CustomerManagementEnum.LAST_CONNECT_TIME.getFieldType());
                entityExt.setSymbol(ConditionEnum.RANGE.getSymbol());
                entityExt.setValue(value);
                // 归档
                ConditionsEntityExt cusArachivedEntityExt = getArachivedCondition(CustomerManagementEnum.IS_ARCHIVED.getAttr(),
                        CustomerManagementEnum.IS_ARCHIVED.getFieldType());
                // 非公海客户
                ConditionsEntityExt cusIsPublicEntityExt = getNoPublicCustomerCondition();

                list.add(entityExt);
                list.add(cusArachivedEntityExt);
                list.add(cusIsPublicEntityExt);
                break;
            // 遗忘机会
            case FORGET_OPPORTUNITY:
                value = getForgetDateRange(now, value, symbol);
                entityExt.setAttr(SalesOpportunityEnum.LAST_CONNECT_TIME.getAttr());
                entityExt.setFieldType(SalesOpportunityEnum.LAST_CONNECT_TIME.getFieldType());
                entityExt.setSymbol(ConditionEnum.RANGE.getSymbol());
                entityExt.setValue(value);
                // 归档条件
                ConditionsEntityExt oppArachivedEntityExt = getArachivedCondition(SalesOpportunityEnum.IS_ARCHIVED.getAttr(),
                        SalesOpportunityEnum.IS_ARCHIVED.getFieldType());
                list.add(entityExt);
                list.add(oppArachivedEntityExt);
                break;
            // 遗忘供应商
            case FORGET_SUPPLIER:
                value = getForgetDateRange(now, value, symbol);
                entityExt.setAttr(SupplierEnum.LAST_CONNECT_TIME.getAttr());
                entityExt.setFieldType(SupplierEnum.LAST_CONNECT_TIME.getFieldType());
                entityExt.setSymbol(ConditionEnum.RANGE.getSymbol());
                entityExt.setValue(value);
                list.add(entityExt);
                break;
            // 未跟进客户
            case NO_CONNECT_CUSTOMER:
                value.clear();
                value.add(0);
                entityExt.setAttr(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr());
                entityExt.setFieldType(CustomerManagementEnum.LAST_CONNECT_TIME.getFieldType());
                entityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
                entityExt.setValue(value);
                // 归档
                ConditionsEntityExt cusArachivedEntityExt1 = getArachivedCondition(CustomerManagementEnum.IS_ARCHIVED.getAttr(),
                        CustomerManagementEnum.IS_ARCHIVED.getFieldType());
                // 非公海客户
                ConditionsEntityExt cusIsPublicEntityExt1 = getNoPublicCustomerCondition();

                list.add(entityExt);
                list.add(cusArachivedEntityExt1);
                list.add(cusIsPublicEntityExt1);
                break;
            // 未跟进供应商
            case NO_CONNECT_SUPPLIER:
                value.clear();
                value.add(0);
                entityExt.setAttr(SupplierEnum.LAST_CONNECT_TIME.getAttr());
                entityExt.setFieldType(SupplierEnum.LAST_CONNECT_TIME.getFieldType());
                entityExt.setSymbol(ConditionEnum.EMPTY.getSymbol());
                entityExt.setValue(value);
                list.add(entityExt);
                break;
            // 合同即将到期
            case CONTRACT_DEAD_LINE:
                list.add(getEstimateTimeRange(ContractEnum.DEADLINE.getAttr(), ContractEnum.DEADLINE.getFieldType(), symbol, value, now));
                break;
            // 销售阶段
            case OPPORTUNITY_STAGE:
                entityExt.setAttr(SalesOpportunityEnum.SALE_STAGE.getAttr());
                entityExt.setFieldType(SalesOpportunityEnum.SALE_STAGE.getFieldType());
                entityExt.setSymbol(symbol);
                entityExt.setValue(value);
                list.add(entityExt);
                break;
            // 采购即将到货
            case PURCHASE_ARRIVE_TIME:
                list.add(getEstimateTimeRange(PurchaseEnum.ESTIMATE_ARRIVE_TIME.getAttr(), PurchaseEnum.ESTIMATE_ARRIVE_TIME.getFieldType(), symbol, value, now));
                break;
            // 生产完成
            case PRODUCTION_ORDER_PLAN_TIME:
                list.add(getEstimateTimeRange(ProductionOrderEnum.PLAN_TIME.getAttr(), ProductionOrderEnum.PLAN_TIME.getFieldType(), symbol, value, now));
                break;
            // 待采购
            case WAIT_PURCHASE:
                if (waitPurchaseDataIdSet.size() > 0) {
                    entityExt.setAttr(FieldTypeEnum.DATAID.getAlias());
                    entityExt.setFieldType(FieldTypeEnum.DATAID.getType());
                    entityExt.setSymbol(ConditionEnum.IN.getSymbol());
                    entityExt.setValue(new ArrayList<>(waitPurchaseDataIdSet));
                    // 归档条件
                    ConditionsEntityExt arachivedEntityExt = getArachivedCondition(ContractEnum.ARCHIVED.getAttr(),
                            ContractEnum.ARCHIVED.getFieldType());
                    // 未处理日期
                    ConditionsEntityExt untreatedEntityExt = getUntreatedDateRange(symbol, now, value);
                    // 是否出库完毕
                    ConditionsEntityExt allOutBoundEntityExt = new ConditionsEntityExt(ContractEnum.ALL_OUT_BOUND.getAttr(),
                            null, ContractEnum.ALL_OUT_BOUND.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(BasicConstant.ZERO));

                    list.add(entityExt);
                    list.add(arachivedEntityExt);
                    list.add(untreatedEntityExt);
                    list.add(allOutBoundEntityExt);
                }
                break;
            // 待生产
            case WAIT_PRODUCTION_ORDER:
                if (waitProduceDataIdSet.size() > 0) {
                    entityExt.setAttr(FieldTypeEnum.DATAID.getAlias());
                    entityExt.setFieldType(FieldTypeEnum.DATAID.getType());
                    entityExt.setSymbol(ConditionEnum.IN.getSymbol());
                    entityExt.setValue(new ArrayList<>(waitProduceDataIdSet));
                    // 归档条件
                    ConditionsEntityExt arachivedEntityExt = getArachivedCondition(ContractEnum.ARCHIVED.getAttr(),
                            ContractEnum.ARCHIVED.getFieldType());

                    // 未处理日期
                    ConditionsEntityExt untreatedEntityExt = getUntreatedDateRange(symbol, now, value);
                    // 是否出库完毕
                    ConditionsEntityExt allOutBoundEntityExt = new ConditionsEntityExt(ContractEnum.ALL_OUT_BOUND.getAttr(),
                            null, ContractEnum.ALL_OUT_BOUND.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(BasicConstant.ZERO));

                    list.add(entityExt);
                    list.add(arachivedEntityExt);
                    list.add(untreatedEntityExt);
                    list.add(allOutBoundEntityExt);
                }
                break;
            // 待入库
            case WAIT_INSTOCK:
                // 未处理日期
                ConditionsEntityExt instockUntreatedEntityExt = getUntreatedDateRange(symbol, now, value);

                value.clear();
                value.add(0);
                entityExt.setAttr(PurchaseEnum.ALL_INCOMING.getAttr());
                entityExt.setFieldType(PurchaseEnum.ALL_INCOMING.getFieldType());
                entityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
                entityExt.setValue(value);
                // 是否入库完毕
                ConditionsEntityExt allIncomingEntityExt = new ConditionsEntityExt(PurchaseEnum.ALL_INCOMING.getAttr(),
                        null, PurchaseEnum.ALL_INCOMING.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(BasicConstant.ZERO));


                list.add(entityExt);
                list.add(instockUntreatedEntityExt);
                list.add(allIncomingEntityExt);
                break;
            // 待出库
            case WAIT_OUTSTOCK:
                // 未处理日期
                ConditionsEntityExt outstockUntreatedEntityExt = getUntreatedDateRange(symbol, now, value);

                value.clear();
                value.add(0);
                entityExt.setAttr(ContractEnum.ALL_OUT_BOUND.getAttr());
                entityExt.setFieldType(ContractEnum.ALL_OUT_BOUND.getFieldType());
                entityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
                entityExt.setValue(value);
                // 归档条件
                ConditionsEntityExt waitArachivedEntityExt = getArachivedCondition(ContractEnum.ARCHIVED.getAttr(),
                        ContractEnum.ARCHIVED.getFieldType());
                // 是否出库完毕
                ConditionsEntityExt allOutBoundEntityExt = new ConditionsEntityExt(ContractEnum.ALL_OUT_BOUND.getAttr(),
                        null, ContractEnum.ALL_OUT_BOUND.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(BasicConstant.ZERO));

                list.add(entityExt);
                list.add(waitArachivedEntityExt);
                list.add(outstockUntreatedEntityExt);
                list.add(allOutBoundEntityExt);
                break;
            case PRODUCT_STOCK_LOWER_WARNING:
                // 产品库存下限预警
                Set<Long> productStockLowerList = getProductIdList(corpid, FieldTypeEnum.CHECKED_WAREHOUSE_LOWER_LIMIT);
                ConditionsEntityExt productStockLower = new ConditionsEntityExt(FieldTypeEnum.DATAID.getAlias(), "", FieldTypeEnum.DATAID.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(productStockLowerList));
                list.add(productStockLower);
                break;
            case PRODUCT_STOCK_UPPER_WARNING:
                // 产品库存上限预警
                Set<Long> productStockUpperList = getProductIdList(corpid, FieldTypeEnum.CHECKED_WAREHOUSE_UPPER_LIMIT);
                ConditionsEntityExt productUpperLower = new ConditionsEntityExt(FieldTypeEnum.DATAID.getAlias(), "", FieldTypeEnum.DATAID.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(productStockUpperList));
                list.add(productUpperLower);
                break;
            // 产品临期
            case PRODUCT_EXPIRE_WARNING:
                // 保质期天数
                entityExt = getExpireTimeRange(corpid, symbol, value, now);
                list.add(entityExt);
                break;
            // 回款到期、回款逾期
            case PAYMENT_DEAD_LINE:
            case PAYMENT_OVERDUE:
                list.add(getEstimateTimeRange(PaymentEnum.ESTIMATE_TIME.getAttr(), PaymentEnum.ESTIMATE_TIME.getFieldType(), symbol, value, now));
                // 回款状态
                list.add(getPaymentOrPayPlanStatusCondition(true));
                break;
            // 付款到期、回款逾期
            case PAY_PLAN_DEAD_LINE:
            case PAY_PLAN_OVERDUE:
                list.add(getEstimateTimeRange(PayPlanEnum.ESTIMATE_TIME.getAttr(), PayPlanEnum.ESTIMATE_TIME.getFieldType(), symbol, value, now));
                // 付款状态
                list.add(getPaymentOrPayPlanStatusCondition(false));
                break;
            default:
                break;
        }

        return list;
    }


    /**
     * 保质期筛选条件
     *
     * @param symbol 操作符
     * @param value 值列表
     * @param now 当前日期（时间戳）
     * @throws
     * @return
     * @author hongxiao
     * @date 2019-12-17 15:19
     * @since
     * @version
     */
    public ConditionsEntityExt getExpireTimeRange( String corpid, String symbol, List<Object> value, long now) {
        ConditionsEntityExt entityExt = new ConditionsEntityExt();
        entityExt.setAttr(FieldTypeEnum.DATAID.getAlias());
        entityExt.setFieldType(FieldTypeEnum.DATAID.getType());
        entityExt.setSymbol(ConditionEnum.IN.getSymbol());
        try {
            // 保质期：大于、大于等于、小于、小于等于、选择范围
            ConditionEnum conditionEnum = ConditionEnum.getConditionEnum(symbol);
            List<Object> timeRange = new ArrayList<>(2);
            if (conditionEnum == null) {
                timeRange.add(now);
                timeRange.add(now + TimeConstant.SECONDS_PER_DAY);
                symbol = ConditionEnum.RANGE.getSymbol();
            } else {
                long startDay = 0;
                long endDay = 0;
                if (value.size() == BasicConstant.TWO) {
                    startDay = Long.parseLong(value.get(0).toString());
                    endDay = Long.parseLong(value.get(1).toString());
                } else if (value.size() == BasicConstant.ONE) {
                    startDay = Long.parseLong(value.get(0).toString());
                }
                switch (conditionEnum) {
                    // 大于
                    case GREATERTHAN:
                        timeRange.add(now + (startDay + 1) * TimeConstant.SECONDS_PER_DAY);
                        break;
                    // 大于等于/小于等于
                    case GREATEREQUAL:
                    case LESSEQUAL:
                        timeRange.add(now + startDay * TimeConstant.SECONDS_PER_DAY);
                        break;
                    // 小于
                    case LESSTHAN:
                        timeRange.add(now + (startDay - 1) * TimeConstant.SECONDS_PER_DAY);
                        break;
                    case RANGE:
                        timeRange.add(now + startDay * TimeConstant.SECONDS_PER_DAY);
                        timeRange.add(now + (endDay + 1) * TimeConstant.SECONDS_PER_DAY);
                        break;
                    default:
                        break;
                }
            }
            // 获取过期日期范围内的数据
            List<PaasFormDataEntity> list = productStockModel.getWithInExpirationDateList(corpid, symbol, timeRange);
            if (CollectionsUtil.isNotEmpty(list)) {
                List<Object> productIdList = new ArrayList<>();
                list.forEach(item->{
                   if (Objects.nonNull(item.getData()) && Objects.nonNull(item.getData().get(ProductStockSubFormEnum.PRODUCT_ID.getDataAttr()))) {
                       productIdList.add(item.getData().getLong(ProductStockSubFormEnum.PRODUCT_ID.getDataAttr()));
                   }
                });
                entityExt.setValue(productIdList);
                return entityExt;
            }
        } catch (Exception e) {
            LOGGER.error("产品到期提醒com.xbongbong.pro.aiassistant.AiAssistantConditionHelp.getExpireTimeRange error", e);
        }
        entityExt.setValue(Arrays.asList(-1));
        return entityExt;
    }

    /**
     * 获取未处理筛选条件（待采购/待生产/待出库/待入库）
     *
     * @param value 值列表
     * @param now 当前日期（时间戳）
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-16 10:06
     * @since v1.0
     * @version v1.0
     */
    public static  ConditionsEntityExt getUntreatedDateRange(String symbol, long now, List<Object> value) {

        // 待：大于、大于等于、小于、小于等于、选择范围
        ConditionEnum conditionEnum = ConditionEnum.getConditionEnum(symbol);
        List<Object> timeRange = new ArrayList<>(BasicConstant.TWO);
        if (conditionEnum == null) {
            timeRange.add(now);
            timeRange.add(now + TimeConstant.SECONDS_PER_DAY);
            symbol = ConditionEnum.RANGE.getSymbol();
        } else {
            long startDay = 0;
            long endDay = 0;
            if (value.size() == BasicConstant.TWO) {
                startDay = Long.parseLong(value.get(0).toString());
                endDay = Long.parseLong(value.get(1).toString());
            } else if (value.size() == BasicConstant.ONE) {
                startDay = Long.parseLong(value.get(0).toString());
            }
            // 创建时间小于当前时间（大于5天，即5天之前）
            switch (conditionEnum) {
                // 大于
                case GREATERTHAN:
                    timeRange.add(now - startDay * TimeConstant.SECONDS_PER_DAY);
                    symbol = ConditionEnum.LESSTHAN.getSymbol();
                    break;
                // 大于等于
                case GREATEREQUAL:
                    timeRange.add(now - (startDay - 1) * TimeConstant.SECONDS_PER_DAY);
                    symbol = ConditionEnum.LESSEQUAL.getSymbol();
                    break;
                // 小于
                case LESSTHAN:
                    timeRange.add(now - (startDay - 1) * TimeConstant.SECONDS_PER_DAY);
                    timeRange.add(now);
                    symbol = ConditionEnum.RANGE.getSymbol();
                    break;
                // 小于等于
                case LESSEQUAL:
                    timeRange.add(now - startDay * TimeConstant.SECONDS_PER_DAY);
                    timeRange.add(now);
                    symbol = ConditionEnum.RANGE.getSymbol();
                    break;
                case RANGE:
                    timeRange.add(now - endDay * TimeConstant.SECONDS_PER_DAY);
                    timeRange.add(now - (startDay - 1) * TimeConstant.SECONDS_PER_DAY);
                    symbol = ConditionEnum.RANGE.getSymbol();
                    break;
                default:
                    break;
            }
        }

        ConditionsEntityExt entityExt = new ConditionsEntityExt();
        // attr、fieldType、symbol、value改为查询的类型
        entityExt.setAttr(FieldTypeEnum.ADDTIME.getAlias());
        entityExt.setFieldType(FieldTypeEnum.ADDTIME.getType());
        entityExt.setSymbol(symbol);
        entityExt.setValue(timeRange);
        return entityExt;
    }

    /**
     * 获取回款/付款的到期/逾期筛选条件
     *
     * @param attr 别名
     * @param fieldType 类型
     * @param symbol 操作符
     * @param value 值列表
     * @param now 当前日期（时间戳）
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-02 10:27
     * @since v1.0
     * @version v1.0
     */
    public static  ConditionsEntityExt getEstimateTimeRange(String attr, Integer fieldType, String symbol, List<Object> value, long now) {

        long day = 0;
        if (value.size() > 0) {
            day = Long.parseLong(value.get(0).toString());
        }
        // 查询条件为时间区间
        value = getDateRange(now, day, symbol);
        // 条件为区间
        symbol = ConditionEnum.RANGE.getSymbol();

        ConditionsEntityExt entityExt = new ConditionsEntityExt();
        // attr、fieldType、symbol、value改为查询的类型
        entityExt.setAttr(attr);
        entityExt.setFieldType(fieldType);
        entityExt.setSymbol(symbol);
        entityExt.setValue(value);
        return entityExt;
    }




    /**
     * 获取回款或付款状态筛选条件
     *
     * @param isPayment 是回款还是付款
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-24 19:46
     * @since
     * @version
     */
    public ConditionsEntityExt getPaymentOrPayPlanStatusCondition(boolean isPayment) {

        String attr = isPayment ? PaymentEnum.STATUS.getAttr() : PayPlanEnum.STATUS.getAttr();
        Integer fieldType = isPayment ? PaymentEnum.STATUS.getFieldType() : PayPlanEnum.STATUS.getFieldType();

        // 回款或付款状态
        List<Object> statusList = isPayment ? Arrays.asList(PaymentStatusEnum.UN_RECEIVABLES.getCode(),PaymentStatusEnum.PARTIAL_RECEIPTS.getCode()) :
                Arrays.asList(PayPlanStatusEnum.UN_RECEIVABLES.getCode(),PayPlanStatusEnum.PARTIAL_RECEIPTS.getCode());

        ConditionsEntityExt statusEntityExt = new ConditionsEntityExt();
        statusEntityExt.setAttr(attr);
        statusEntityExt.setFieldType(fieldType);
        statusEntityExt.setSymbol(ConditionEnum.IN.getSymbol());
        // 未回款，部分回款
        statusEntityExt.setValue(statusList);
        return statusEntityExt;
    }
    /**
     * 获取归档筛选条件
     *
     * @param attr      别名
     * @param fieldType 类型
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-07-30 15:58
     * @version v1.0
     * @since v1.0
     */
    public ConditionsEntityExt getArachivedCondition(String attr, Integer fieldType) {
        ConditionsEntityExt arachivedEntityExt = new ConditionsEntityExt();
        arachivedEntityExt.setAttr(attr);
        arachivedEntityExt.setFieldType(fieldType);
        arachivedEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
        arachivedEntityExt.setValue(Collections.singletonList(ArchivedEnum.UN_ARCHIVED.getCode()));

        return arachivedEntityExt;
    }

    /**
     * 获取查询条件可用的时间
     *
     * @param now    当前日期时间戳
     * @param day    天数
     * @param symbol 条件
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-05-09 14:04
     * @version v1.0
     * @since v1.0
     */
    public static  List<Object> getDateRange(long now, long day, String symbol) {
        List<Object> timeRange = new ArrayList<>(BasicConstant.TWO);
        SmartSettingsConditionEnum conditionEnum = SmartSettingsConditionEnum.getBySymbol(symbol);

        if (conditionEnum == null) {
            timeRange.add(now);
            timeRange.add(now + TimeConstant.SECONDS_PER_DAY);
            return timeRange;
        }
        switch (conditionEnum) {
            // 之前
            case BEFORE:
                timeRange.add(now + day * TimeConstant.SECONDS_PER_DAY);
                timeRange.add(now + (day + 1) * TimeConstant.SECONDS_PER_DAY);
                break;
            // 之后
            case AFTER:
                timeRange.add(now - day * TimeConstant.SECONDS_PER_DAY);
                timeRange.add(now - (day - 1)  * TimeConstant.SECONDS_PER_DAY);
                break;
            // 当天
            default:
                timeRange.add(now);
                timeRange.add(now + TimeConstant.SECONDS_PER_DAY);
                break;
        }
        return timeRange;
    }

    /**
     * 获取查询条件可用的遗忘时间区间（时间戳）
     *
     * @param now    当前日期
     * @param value  时间值
     * @param symbol 条件
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-05-09 14:07
     * @version v1.0
     * @since v1.0
     */
    public static  List<Object> getForgetDateRange(long now, List<Object> value, String symbol) {

        List<Object> timeRange = new ArrayList<>(BasicConstant.TWO);
        ConditionEnum conditionEnum = ConditionEnum.getConditionEnum(symbol);
        // 不正确的条件，默认设为当天条件
        if (conditionEnum == null) {
            return timeRange;
        }

        long startDay = 0;
        long endDay = 0;
        if (value.size() == BasicConstant.TWO) {
            startDay = Long.parseLong(value.get(0).toString());
            endDay = Long.parseLong(value.get(1).toString());
        } else if (value.size() == BasicConstant.ONE) {
            startDay = Long.parseLong(value.get(0).toString());
        }

        switch (conditionEnum) {
            // 遗忘提醒都是区间（不包含未跟进客户/机会/供应商）
            case GREATERTHAN:
                timeRange.add(1L);
                timeRange.add(now - startDay * TimeConstant.SECONDS_PER_DAY);
                break;
            case GREATEREQUAL:
                // 初值必须大于0
                timeRange.add(1L);
                timeRange.add(now - (startDay - 1) * TimeConstant.SECONDS_PER_DAY);
                break;
            case LESSTHAN:
                timeRange.add(now - (startDay - 1) * TimeConstant.SECONDS_PER_DAY);
                timeRange.add(now);
                break;
            case LESSEQUAL:
                timeRange.add(now - startDay * TimeConstant.SECONDS_PER_DAY);
                timeRange.add(now);
                break;
            case RANGE:
                timeRange.add(now - endDay * TimeConstant.SECONDS_PER_DAY);
                timeRange.add(now - startDay * TimeConstant.SECONDS_PER_DAY);
                break;
            default:
                break;
        }
        return timeRange;
    }

    /**
     * 获取非公海客户筛选条件
     *
     * @param
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-07-30 16:00
     * @since v1.0
     * @version v1.0
     */
    public ConditionsEntityExt getNoPublicCustomerCondition() {
        ConditionsEntityExt cusIsPublicEntityExt = new ConditionsEntityExt();
        cusIsPublicEntityExt.setAttr(CustomerManagementEnum.IS_PUBLIC.getAttr());
        cusIsPublicEntityExt.setFieldType(CustomerManagementEnum.IS_PUBLIC.getFieldType());
        cusIsPublicEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
        cusIsPublicEntityExt.setValue(Collections.singletonList(0));
        return cusIsPublicEntityExt;
    }

    private Set<Long> getProductIdList(String corpid, FieldTypeEnum lowerWarnTypeEnum) {
        Set<Long> productIdSet = new HashSet<>();
        productIdSet.add(-1L);
        try {
            BoolQueryBuilder parentBoolQueryBuilder = boolQuery();
            parentBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            parentBoolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            parentBoolQueryBuilder.mustNot(termQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.PARENT_ID),0));
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            List<ConditionsEntityExt> conditionList = new ArrayList<>();
            boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            conditionList.add(new ConditionsEntityExt(ProductWarehouseSubFormEnum.IS_NOTIFY.getDataAttr(),"",ProductWarehouseSubFormEnum.IS_NOTIFY.getFieldType(),ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(1)));
            conditionList.add(new ConditionsEntityExt(ProductWarehouseSubFormEnum.WAREHOUSE_CHECKED.getDataAttr(),"",ProductWarehouseSubFormEnum.WAREHOUSE_CHECKED.getFieldType(),ConditionEnum.EQUAL.getSymbol(),Collections.singletonList(1)));
            //解析查询条件
            EsUtil.parseCondition(boolQueryBuilder,conditionList, "", corpid, XbbRefTypeEnum.PRODUCT.getCode());

            List<ConditionsEntityExt> productStockLowerList = new ArrayList<>();
            productStockLowerList.add(new ConditionsEntityExt(lowerWarnTypeEnum.getAlias(),"",lowerWarnTypeEnum.getType(),ConditionEnum.EQUAL.getSymbol(),Collections.singletonList(1)));
            EsUtil.parseProductSearchCondition(boolQueryBuilder, productStockLowerList, "", corpid, XbbRefTypeEnum.WARNING_SEARCH.getCode());
            HasParentQueryBuilder hasParentQueryBuilder = JoinQueryBuilders.hasParentQuery(IndexTypeEnum.IDX_SAAS_PRODUCT.getType(), parentBoolQueryBuilder, false);
            boolQueryBuilder.filter(hasParentQueryBuilder);

            List<PaasFormDataEntity> productWarehouseList = paasEsModel.getDataList(boolQueryBuilder, IndexTypeEnum.IDX_SAAS_PRODUCT_WAREHOUSE, new ArrayList<>(), 1,
                    SizeConstant.PAGE_SIZE, PaasFormDataEntity.class, FieldTypeEnum.UPDATETIME.getAlias(), SortOrder.DESC);
            if (productWarehouseList == null) {
                productWarehouseList = new ArrayList<>();
            }
            List<ProductWarehouseEntity> productWarehouseEntities = transferSubFormHelper.transferFormDataToProductWarehouseList(productWarehouseList);

            for (ProductWarehouseEntity productWarehouseEntity : productWarehouseEntities) {
                productIdSet.add(productWarehouseEntity.getProductId());
            }
        } catch (Exception e) {
            LOGGER.error("获取库存上下限出错", e);
        }
        return productIdSet;
    }
}
